package com.koron.auth.filter;

import cn.hutool.core.util.StrUtil;
import com.koron.auth.service.CommonWebService;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.Constant;
import com.koron.bean.util.JWTUtils;
import com.koron.common.core.business.log.entity.po.LogLoginPo;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.IpUtil;
import com.koron.common.core.util.SpringUtils;
import com.koron.common.core.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class LoginFilter implements Filter {


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        log.info("LoginFilter doFilter start...");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        CustomHttpServletResponseWrapper customHttpServletResponseWrapper = new CustomHttpServletResponseWrapper(response);

        filterChain.doFilter(servletRequest, customHttpServletResponseWrapper);

        String redirectUrl = customHttpServletResponseWrapper.getRedirectUrl();
        log.info("redirectUrl = {}", redirectUrl);

        String currDs = StrUtil.subBetween(redirectUrl,"currDs=","&");
        log.info("logging currDs = {}", currDs);
        // request.setAttribute(Constant.DYNAMIC_DATA_SOURCE,currDs);
        String token = response.getHeader("jwt_token");
        if (!StringUtils.isEmpty(token)) {
            //String currDs = request.getParameter("currDs");
            response.setHeader("currDs",currDs);
            try {
                Map<String, String> map = JWTUtils.payload(token);
                saveLoginInfo(map,currDs,request);
            } catch (Exception e) {
                log.error("logging user login info error = {}", e.getMessage());
            }
        }
        log.info("LoginFilter doFilter end...");
    }

    public void saveLoginInfo(Map<String,String> map, String currDs, HttpServletRequest request) throws Exception {

        Map<String,String> headers = new HashMap<>();
        headers.put("currDs", currDs);

        log.info("map = {}", map);
        CommonWebService commonWebService = SpringUtils.getBean(CommonWebService.class);
        log.info("commonWebService = {}", commonWebService);
        InetAddress localHost = InetAddress.getLocalHost();
        String hostAddress = request == null ? localHost.getHostAddress() : IpUtil.getIpAddr(request);
        String hostName = localHost.getHostName();
        Date loginTime = new Date();
        String account = map.get(Constant.ACCOUNT);
        String name = map.get(Constant.USERNAME);
        String appid = map.get("appId");
        LogLoginPo logLoginPo = new LogLoginPo();
        logLoginPo.setId(CodeTools.getCode32());
        logLoginPo.setIp(hostAddress);
        logLoginPo.setHost(hostName);
        logLoginPo.setInTime(loginTime);
        logLoginPo.setAccount(account);
        logLoginPo.setName(name);
        logLoginPo.setAppId(appid);
        Response<String> result = commonWebService.saveLogLogin(headers, logLoginPo);

        log.info("LoginFilter:saveLogLogin:result={}", Integer.valueOf(String.valueOf(result)) > 0 ? "success" : "fail");
    }

    class CustomHttpServletResponseWrapper extends HttpServletResponseWrapper{

        private String redirectUrl;

        public CustomHttpServletResponseWrapper(HttpServletResponse response) {
            super(response);
        }

        @Override
        public void sendRedirect(String location) throws IOException {
            this.redirectUrl = location;
            super.sendRedirect(location);
        }

        public String getRedirectUrl() {
            return redirectUrl;
        }
    }
}
